package com.bms.zuul.config;


import com.bms.zuul.filter.MyLogoutFilter;
import com.bms.zuul.filter.MyRolesAuthorizationFilter;
import com.bms.zuul.filter.MyUserFilter;
import com.bms.zuul.util.UserRealm;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author zcx
 * @version 1.0
 * @description ShiroConfiguration.java
 */
@Configuration
public class ShiroConfiguration {

    //将自己的验证方式加入容器
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    /**
     * cookie对象;
     * @return
     */
    public SimpleCookie rememberMeCookie(){
        System.out.println("ShiroConfiguration rememberMeCookie--------------------------------------------");
        //这个参数是cookie的名称
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        //<!-- 记住我cookie生效时间30天 ,单位秒;-->
        simpleCookie.setMaxAge(2592000);
        return simpleCookie;
    }

    /**
     * cookie管理对象;记住我功能
     * @return
     */
    public CookieRememberMeManager rememberMeManager(){
        System.out.println("ShiroConfiguration rememberMeManager--------------------------------------------");
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
        cookieRememberMeManager.setCipherKey(Base64.decode("4KaYtkFJPs0KSA3Kprsdag=="));
        // think md5->md5->md5设定次数666   asd678sa6d78sa6d78sa6d7sads    4KaYt t kFJPs h 0KSA i 3K n prsdag== k
        // 4KaYtktFJPs0hKSAi3Knprsdag==k
        return cookieRememberMeManager;
    }

    //权限管理，配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置自定义验证规则
        securityManager.setRealm(userRealm());
        // 设置自定义rememeberMe
        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;
    }

    //Filter工厂，设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 自定义退出LogoutFilter
        Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
        System.out.println("filterMap=" + filterMap);
        MyLogoutFilter myLogoutFilter = new MyLogoutFilter();  // 退出处理   /logout
//        myLogoutFilter.setRedirectUrl("/login.html");
//        //自定义的filter 不能交给spring 容器管理，只能使用new 实例化filter
//        // 在当前版本中，有一个bug，首先装载authc，再装载logout，否则在退出处理的时候，boot工程会报错
//        filterMap.put("authc", new MyFormAuthenticationFilter());
        filterMap.put("authc", new MyUserFilter());
        filterMap.put("roles",new MyRolesAuthorizationFilter());
        filterMap.put("logout", myLogoutFilter);

        Map<String, String> map = new LinkedHashMap<>();  // shiro要求必须是LinkedHashMap
        map.put("/js/**","anon");  // anon  放行
        map.put("/css/**","anon");
        map.put("/jquery/**","anon");
        map.put("/img/**","anon");
        map.put("/swagger-resources/**","anon");
        map.put("/webjars/**","anon");
        map.put("/v2/**","anon");
        map.put("/swagger-ui.html","anon");
        map.put("/swagger-ui.html/**","anon");
        map.put("/user/login","anon");
        map.put("/user/reg","anon");
        map.put("/logout","logout");        //  退出
        map.put("/feiYongGuanLi/gengXinShenHeById","roles[2]");//  权限管理
        map.put("/feiYongGuanLi/gengXinBoKuanById","roles[2]");
        map.put("/feiYongGuanLi/shanChu","roles[2]");
        map.put("/feiYongGuanLi/chaXunFenYe","roles[2]");
        map.put("/feiYongGuanLi/xinZengXiangMuJingFei","roles[1,2,3]");
        map.put("/feiYongGuanLi/xinZengHeZuoJingFei","roles[1,2,3]");
        map.put("/feiYongGuanLi/xinZengChuLaiJingFei","roles[1,2,3]");
        map.put("/ChuFangGuanLi/**","roles[1,2,3]");
        map.put("/duiWaiXinXiJiaoLiu/**","roles[1,2,3]");
        map.put("/heZuoJiHuaGuanLi/**","roles[1,2,3]");
        map.put("/laiFangGuanLi/**","roles[1,2,3]");
        map.put("/xiangGuanWenDang/**","roles[1]");
        map.put("/keYanXiangMuGuanLi/**","roles[1]");
        map.put("/guanLiLunWen/**","roles[0,1,2,3]");
        map.put("/KeYanZhiLiangKongZhi/**","roles[2]");
        map.put("text.html","roles[2]");
        //对所有用户认证
        map.put("/**","authc");     // authc 拦截
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //加入注解的使用，不加入这个注解不生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        return new DefaultAdvisorAutoProxyCreator();
    }

}
